package com.scientific.research.gobang.service.codegame.impl;

import com.scientific.research.gobang.Utils.RedisUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.scientific.research.gobang.pojo.RankUser;
import com.scientific.research.gobang.pojo.User;
import com.scientific.research.gobang.mapper.RankingMapper;
import com.scientific.research.gobang.service.CodeGameService;
import com.scientific.research.gobang.utils.RocketMqUtils;
import com.scientific.research.gobang.service.UserService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class CodeGameServiceImpl implements CodeGameService {
    @Autowired
    RankingMapper rankingMapper;
    @Autowired
    UserService userService;
    @Resource
    RedisUtil redisUtil;
    @Autowired
    RedissonClient redissonClient;

    @SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
    @Override
    public List<Object> LodeUserTable() {
        List list = (List) redisUtil.get("gobang_rankUser");

        if (list == null) { //如果从Redis缓存中无法读取到数据，就从数据库中查询
            RLock lock = redissonClient.getLock("gobang_rankUser");
            lock.lock(15, TimeUnit.SECONDS);// Redisson分布式锁,防止缓存击穿

            list = (List) redisUtil.get("gobang_rankUser");// 再从Redis获取一次，如果没获取到就从数据库查
            if (list == null) {
                QueryWrapper<RankUser> wrapper = new QueryWrapper<>();
                wrapper.orderByDesc("rank_fractions");
                list = rankingMapper.selectObjs(wrapper);
                //将查询结果放入Redis缓存中，以后查询就可以从缓存中读取
                redisUtil.set("gobang_rankUser", list);
                //解锁
                lock.unlock();
            }
        }
        return list;
    }

    //执行用户提交的代码
    @SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
    @Override
    public void SaveRunCode(Map map) {
        Map<String, Object> sendMap = new HashMap<>();
        sendMap.put("fightUser", map.get("fightUser"));
        sendMap.put("language", map.get("language"));
        sendMap.put("code", map.get("code"));
        User user = userService.LodeUserMessage(map);
        sendMap.put("email", user.getEmail());
        RocketMqUtils.runCodeSendMessage(sendMap);
        redisUtil.set(user.getEmail() + "_runCode", (int) redisUtil.get(user.getEmail() + "_runCode") + 1);
    }
}
